<?php

namespace yi\base;

use Yi;

class Module extends \yi\di\ServiceLocator
{
    public $controllerNamespace;
    public $defaultRoute = 'default';
    /**
     * @var string
     */
    private $_viewPath;    /**
     * @var string
     */
    private $_basePath;


    public function runAction($route, $params)
    {
        $parts = $this->createController($route);
        if (is_array($parts)) {
            /* @var $controller Controller */
            list($controller, $actionID) = $parts;
            Yi::$app->controller=$controller;
            $result = $controller->runAction($actionID, $params);
            return $result;
        }

    }

    public function createController($route)
    {
        if ($route === '') {
            $route = $this->defaultRoute;
        }

        // double slashes or leading/ending slashes may cause substr problem
        $route = trim($route, '/');
        if (strpos($route, '//') !== false) {
            return false;
        }

        if (strpos($route, '/') !== false) {
            list($id, $route) = explode('/', $route, 2);
        } else {
            $id = $route;
            $route = '';
        }


        $controller = $this->createControllerByID($id);
        if ($controller === null && $route !== '') {
            $controller = $this->createControllerByID($id . '/' . $route);
            $route = '';
        }

        return $controller === null ? false : [$controller, $route];
    }

    public function createControllerByID($id)
    {
        $className = $id;
        $className = preg_replace_callback('%-([a-z0-9_])%i', function ($matches) {
                return ucfirst($matches[1]);
            }, ucfirst($className)) . 'Controller';
        $className = ltrim($this->controllerNamespace . '\\'. $className, '\\');
        if (!class_exists($className)) {
            return null;
        }

        if (is_subclass_of($className, 'yi\base\Controller')) {
            $controller = Yi::createObject($className, [$id, $this]);
            return get_class($controller) === $className ? $controller : null;
        }
    }


    public function getViewPath()
    {
        if ($this->_viewPath === null) {
            $this->_viewPath = $this->getBasePath() . DIRECTORY_SEPARATOR . 'views';
        }

        return $this->_viewPath;
    }

    public function getBasePath()
    {
        if ($this->_basePath === null) {
            $class = new \ReflectionClass($this);
            $this->_basePath = dirname($class->getFileName());
        }

        return $this->_basePath;
    }

    public function setBasePath($path)
    {
        $path = Yi::getAlias($path);
        $p = strncmp($path, 'phar://', 7) === 0 ? $path : realpath($path);
        if (is_string($p) && is_dir($p)) {
            $this->_basePath = $p;
        } else {
            throw new \Exception("The directory does not exist: $path");
        }
    }

}
